package com.bcdbook.activiti.web;

import com.bcdbook.activiti.convertor.Task2SimpleTaskConvertor;
import com.bcdbook.activiti.form.TaskCompleteForm;
import com.bcdbook.activiti.security.SecurityUtil;
import com.bcdbook.activiti.support.SimpleTask;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.task.Task;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

/**
 * 任务的控制器
 *
 * @author summer
 * @version V1.0.0-RELEASE
 * DateTime 2019-03-22 12:45
 */
@RestController
@RequestMapping("/task")
@Slf4j
public class TaskController {

    /**
     * 注入任务的 service
     */
    @Resource
    private TaskService taskService;

    /**
     * 注入 Security 的工具类
     */
    @Resource
    private SecurityUtil securityUtil;

    /**
     * 查询所有的正在执行的 任务
     *
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 15:54
     */
    @GetMapping
    public List<SimpleTask> listAllActiveTask(){
        List<Task> taskList = taskService.createTaskQuery()
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }

    /**
     * 根据任务的 id 获取简单任务对象的方法
     *
     * @param taskId 任务 id
     * @return com.bcdbook.activiti.support.SimpleTask
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-27 14:37
     */
    @GetMapping("/{taskId}")
    public SimpleTask getActiveTaskById(@PathVariable(name = "taskId") String taskId) {
        // 执行查询
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();

        return Task2SimpleTaskConvertor.convert(task);
    }

    /**
     * 根据流程实例的 id 查询节点集合
     *
     * @param processInstanceId 根据流程实例的 id
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-27 13:17
     */
    @GetMapping("/process/{processInstanceId}")
    public List<SimpleTask> listActiveTaskByProcessInstanceId(@PathVariable(name = "processInstanceId")
                                                                    String processInstanceId){
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }


    /**
     * 根据业务的 key 查询对应的任务
     *
     * @param businessKey 业务的 key
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 15:55
     */
    @GetMapping("/business")
    public List<SimpleTask> listActiveTaskByBusinessKey(@RequestParam(required = false) String businessKey){
        List<Task> taskList = taskService.createTaskQuery()
                .processInstanceBusinessKey(businessKey)
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }

    /**
     * 根据任务的候选人查询任务信息
     *
     * @param candidateUser 任务候选人
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 12:39
     */
    @GetMapping("/candidateUser")
    public List<SimpleTask> listActiveTaskByCandidateUser(@RequestParam String candidateUser){
        List<Task> taskList = taskService.createTaskQuery()
                .taskCandidateUser(candidateUser)
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }

    /**
     * 根据任务的候选人组别查询任务信息
     *
     * @param candidateGroup 任务候选人组别
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 12:39
     */
    @GetMapping("/candidateGroup")
    public List<SimpleTask> listActiveTaskByCandidateGroup(@RequestParam String candidateGroup){
        List<String> candidateGroupList = new ArrayList<>();
        candidateGroupList.add(candidateGroup);

        List<Task> taskList = taskService.createTaskQuery()
                .taskCandidateGroupIn(candidateGroupList)
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }

    /**
     * 根据任务的受理人查询任务信息
     *
     * @param assignee 任务受理人
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 12:39
     */
    @GetMapping("/assignee")
    public List<SimpleTask> listActiveTaskByAssignee(@RequestParam(required = false) String assignee){
        List<Task> taskList = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }

    /**
     * 根据任务的所有者查询任务
     *
     * @param owner 任务所有者
     * @return java.util.List<com.bcdbook.activiti.support.SimpleTask>
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 12:48
     */
    @GetMapping("/owner")
    public List<SimpleTask> listActiveTaskByOwner(@RequestParam(required = false) String owner){
        List<Task> taskList = taskService.createTaskQuery()
                .taskOwner(owner)
                .list();

        return Task2SimpleTaskConvertor.convert(taskList);
    }

    /**
     * 任务认领
     *
     * @param taskId 任务 id
     * @param userId 用户 id
     * @return void
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 14:49
     */
    @PostMapping("/claim")
    public void claim(String taskId, String userId){

        taskService.claim(taskId, userId);

        log.info("任务: {}, 已经被: {} 认领", taskId, userId);
    }

    /**
     * 任务委派
     *
     * @param taskId 任务 id
     * @param userId 用户 id
     * @return void
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 14:49
     */
    @PostMapping("/delegate")
    public void delegate(String taskId, String userId){
        taskService.delegateTask(taskId, userId);

        log.info("任务: {}, 已经委派给: {}", taskId, userId);
    }

    /**
     * 任务审批的方法
     *
     * @param taskCompleteForm 审批任务的表单
     * @return void
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 14:29
     */
    @PostMapping("/complete")
    public void complete(@NotNull(message = "任务审批表单不能为空") @Valid
                             @RequestBody TaskCompleteForm taskCompleteForm){

        // 执行审批前的相关操作
        preComplete(taskCompleteForm);

        // 获取在线用户
        UserDetails userDetails = securityUtil.getActiveUserDetails();
        // 设置了此数据以后, activiti 会自动设置 start id 等信息
        // TODO 此操作之后要放到认证完成后的方法上
        Authentication.setAuthenticatedUserId(userDetails.getUsername());

        // 执行审批
        taskService.complete(taskCompleteForm.getTaskId(), taskCompleteForm.getTaskValue());

        log.info("Task complete, TaskCompleteForm: {}", taskCompleteForm);

    }

    /**
     * 被委派的任务的审批方法
     *
     * @param taskId 任务的 id
     * @return void
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-22 14:29
     */
    @PostMapping("/resolve")
    public void resolve(String taskId){
        taskService.resolveTask(taskId);

        log.info("Task resolve, The task is: {}", taskId);
    }

    /**
     * 审批前执行的一些扩展操作
     *
     * @param taskCompleteForm 审批时提交的表单
     * @return void
     * Author summer
     * Version V1.0.0-RELEASE
     * DateTime 2019-03-27 14:03
     */
    private void preComplete(@NotNull(message = "任务审批表单不能为空") @Valid TaskCompleteForm taskCompleteForm) {
        /*
         * 审批人设置
         */
        // 获取审批人
        String assignee = taskCompleteForm.getAssignee();
        // 如果传入的审批人, 则设置审批人
        if (!StringUtils.isEmpty(assignee)) {
            taskService.setAssignee(taskCompleteForm.getTaskId(), assignee);
        }

//        /*
//         * 候选人设置
//         */
//        // 获取候选人集合
//        List<String> candidateUserList = taskCompleteForm.getCandidateUserList();
//        // 如果候选人集合不为空
//        if (!CollectionUtils.isEmpty(candidateUserList)) {
//            // 循环设置候选人
//            candidateUserList.stream()
//                    .filter(Objects::nonNull)
//                    .forEach(userId -> {
//                        taskService.addCandidateUser(taskCompleteForm.getTaskId(), userId);
//                    });
//        }
//
//        /*
//         * 候选人组设置
//         */
//        // 获取候选人组
//        List<String> candidateUserGroupList = taskCompleteForm.getCandidateUserGroupList();
//        // 如果候选人组不为空
//        if (!CollectionUtils.isEmpty(candidateUserGroupList)) {
//            // 循环设置候选人组
//            candidateUserGroupList.stream()
//                    .filter(Objects::nonNull)
//                    .forEach(groupId -> {
//                        taskService.addCandidateGroup(taskCompleteForm.getTaskId(), groupId);
//                    });
//        }

        /*
         * 外置表单设置
         */
        // 获取外置表单的 key
        String formKey = taskCompleteForm.getFormKey();
        // 如果外置表单的 key 不为空
        if (!StringUtils.isEmpty(formKey)) {
            // 查询出任务节点
            Task task = taskService.createTaskQuery()
                    .taskId(taskCompleteForm.getTaskId())
                    .singleResult();
            // 设置外表单
            task.setFormKey(formKey);
            // 执行保存
            taskService.saveTask(task);
        }

//        /*
//         * 提交参数设置
//         */
//        // 获取提交参数
//        Map<String, Object> taskValue = taskCompleteForm.getTaskValue();
//        // 如果提交参数不为空
//        if (!CollectionUtils.isEmpty(taskValue)) {
//            taskService.setVariablesLocal(taskCompleteForm.getTaskId(), taskValue);
//        }
    }
}
